package org.example.aitest.utils.gen;

import io.swagger.annotations.ApiModelProperty;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.example.aitest.dto.InData;
import org.example.aitest.dto.TableColumn;

import javax.persistence.Column;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class PinyinUtils {

    /**
     * 合并多个List<List<InData>>，处理重复和name冲突
     * @param lists 要合并的List<List<InData>>数组
     * @return 合并后的List<List<InData>>
     */
    public static List<List<InData>> mergeInDataLists(List<List<InData>>... lists) {
        // 过滤掉null和空集合，并转换为流
        List<List<List<InData>>> nonEmptyLists = Stream.of(lists)
                .filter(list -> list != null && !list.isEmpty())
                .collect(Collectors.toList());

        // 如果没有非空集合，返回空列表
        if (nonEmptyLists.isEmpty()) {
            return new ArrayList<>();
        }

        // 找出所有非空集合中最大的内部List数量
        int maxSize = nonEmptyLists.stream()
                .mapToInt(List::size)
                .max()
                .orElse(0);

        List<List<InData>> result = new ArrayList<>();

        // 按位置合并处理
        for (int i = 0; i < maxSize; i++) {
            // 收集所有列表中当前位置的InData列表（跳过不存在的索引）
            int finalI = i;
            List<InData> combined = nonEmptyLists.stream()
                    .filter(list -> finalI < list.size())
                    .flatMap(list -> list.get(finalI).stream())
                    .collect(Collectors.toList());

            // 处理合并后的列表
            List<InData> processed = processInDataList(combined);
            result.add(processed);
        }

        return result;
    }

    /**
     * 处理单个List<InData>，去重并解决name冲突
     * @param inDataList 要处理的列表
     * @return 处理后的列表
     */
    private static List<InData> processInDataList(List<InData> inDataList) {
        List<InData> result = new ArrayList<>();
        Set<String> seenComments = new HashSet<>();
        Map<String, Integer> nameCounts = new HashMap<>();

        if (inDataList == null || inDataList.isEmpty()) {
            return result;
        }

        for (InData data : inDataList) {
            if (data == null) {
                continue;
            }

            // 处理comment为null的情况
            String comment = data.getComment() != null ? data.getComment() : "null_comment_" + System.identityHashCode(data);

            if (seenComments.contains(comment)) {
                continue;
            }

            // 处理name冲突
            String originalName = data.getName();
            int count = nameCounts.getOrDefault(originalName, 0);

            if (count > 0) {
                data.setName(originalName + "_t" + count);
            }

            nameCounts.put(originalName, count + 1);
            result.add(data);
            seenComments.add(comment);
        }

        return result;
    }
    public static List<Map<String, Object>> convert(List<List<InData>> inDataLists) {
        List<Map<String, Object>> result = new ArrayList<>();

        for (List<InData> inDataList : inDataLists) {
            Map<String, Object> map = new HashMap<>();
            Map<String, Integer> nameSuffixMap = new HashMap<>(); // 记录 name 需要加的后缀
            Map<String, String> nameCommentMap = new HashMap<>(); // 记录 name 对应的 comment

            for (InData inData : inDataList) {
                String name = inData.getName();
                String comment = inData.getComment();
                Object value = inData.getValue();

                // 检查是否已有相同的 name 和 comment（去重）
                if (nameCommentMap.containsKey(name) && nameCommentMap.get(name).equals(comment)) {
                    continue; // 如果 name 和 comment 都相同，跳过
                }

                // 检查是否已有相同的 name 但不同的 comment
                if (nameCommentMap.containsKey(name)) {
                    int suffix = nameSuffixMap.getOrDefault(name, 0) + 1;
                    nameSuffixMap.put(name, suffix);
                    name = name + "_t" + suffix; // 修改 name
                }

                // 记录 name 和 comment 的对应关系
                nameCommentMap.put(name, comment);

                // 将 name 和 value 存入 map
                map.put(name, value);
            }

            result.add(map);
        }

        return result;
    }
    public static List<TableColumn> mergeTableColumns(List<TableColumn>... lists) {
        List<TableColumn> mergedList = new ArrayList<>();
        Map<String, Integer> nameSuffixMap = new HashMap<>(); // 记录 name 需要加的后缀
        Set<String> commentSet = new HashSet<>(); // 记录已存在的 comment

        for (List<TableColumn> list : lists) {
            for (TableColumn column : list) {
                String name = column.getName();
                String comment = column.getComment();

                // 检查是否已有相同的 comment（去重）
                if (commentSet.contains(comment)) {
                    continue; // 如果 comment 已存在，跳过
                }
                commentSet.add(comment); // 记录新的 comment

                // 检查是否已有同名但不同 comment 的列
                if (nameSuffixMap.containsKey(name.toLowerCase())) {
                    int suffix = nameSuffixMap.get(name.toLowerCase()) + 1;
                    nameSuffixMap.put(name.toLowerCase(), suffix);
                    column.setName(name + "_t" + suffix); // 修改 name
                } else {
                    nameSuffixMap.put(name.toLowerCase(), 0); // 第一次出现，不修改 name
                }

                mergedList.add(column);
            }
        }

        return mergedList;
    }

    /**
     * 根据TableColumn列表过滤并返回合并去重后的List<List<InData>>，并设置isOnly属性
     *
     * @param tableColumnLists 多个TableColumn列表
     * @param mapLists         多个Map列表，与inDataLists位置一一对应
     * @param inDataLists      多个InData列表，与mapLists位置一一对应
     * @return 合并去重后的List<List<InData>>，其中InData的isOnly属性已设置
     */
    public static List<List<InData>> filterAndMergeInData(
            List<List<TableColumn>> tableColumnLists,
            List<List<Map<String, Object>>> mapLists,
            List<List<List<InData>>> inDataLists) {

        // 1. 检查所有TableColumn列表是否都为空
        boolean allEmpty = tableColumnLists.stream()
                .allMatch(list -> list == null || list.isEmpty());

        if (allEmpty) {
            return Collections.emptyList();
        }

        // 2. 收集所有不为空的TableColumn列表中的列名(不区分大小写)和注释
        Set<String> columnNames = tableColumnLists.stream()
                .filter(list -> list != null && !list.isEmpty())
                .flatMap(List::stream)
                .map(TableColumn::getName)
                .map(String::toLowerCase)
                .collect(Collectors.toSet());

        // 收集所有TableColumn的注释
        Set<String> columnComments = tableColumnLists.stream()
                .filter(list -> list != null && !list.isEmpty())
                .flatMap(List::stream)
                .map(TableColumn::getComment)
                .filter(comment -> comment != null && !comment.isEmpty())
                .collect(Collectors.toSet());

        // 3. 检查mapLists和inDataLists大小是否一致
        if (mapLists.size() != inDataLists.size()) {
            throw new IllegalArgumentException("mapLists和inDataLists的大小必须一致");
        }

        // 4. 找出所有匹配位置的完整InData列表组
        List<List<InData>> result = IntStream.range(0, mapLists.size())
                .filter(i -> {
                    List<Map<String, Object>> maps = mapLists.get(i);
                    return maps != null && maps.stream()
                            .anyMatch(map -> map != null
                                    && map.containsKey("columnName")
                                    && columnNames.contains(
                                    map.get("columnName").toString().toLowerCase()));
                })
                .mapToObj(i -> inDataLists.get(i))
                .flatMap(List::stream)
                .map(inDataList -> {
                    // 为每个InData设置isOnly属性
                    inDataList.forEach(inData -> {
                        if (inData != null && inData.getComment() != null) {
                            inData.setIsOnly(columnComments.contains(inData.getComment()));
                        } else {
                            inData.setIsOnly(false);
                        }
                    });
                    return inDataList;
                })
                .collect(Collectors.toList());

        return result;
    }

    /**
     * 根据TableColumn列表过滤并转换Map列表为TableColumn列表
     *
     * @param tableColumnLists 多个TableColumn列表
     * @param mapLists         多个Map列表
     * @return 转换后的TableColumn列表（合并去重）
     */
    public static List<TableColumn> convertMapsToTableColumns(
            List<List<TableColumn>> tableColumnLists,
            List<List<Map<String, Object>>> mapLists) {

        // 1. 检查所有TableColumn列表是否都为空
        boolean allEmpty = tableColumnLists.stream()
                .allMatch(list -> list == null || list.isEmpty());

        if (allEmpty) {
            return Collections.emptyList();
        }

        // 2. 收集所有不为空的TableColumn列表中的列名(不区分大小写)
        Set<String> columnNames = tableColumnLists.stream()
                .filter(list -> list != null && !list.isEmpty())
                .flatMap(List::stream)
                .map(TableColumn::getName)
                .map(String::toLowerCase)
                .collect(Collectors.toSet());

        // 3. 找出所有包含匹配项的Map列表
        List<List<Map<String, Object>>> matchedMapLists = mapLists.stream()
                .filter(list -> list != null && !list.isEmpty())
                .filter(list -> list.stream()
                        .anyMatch(map -> map != null
                                && map.containsKey("columnName")
                                && columnNames.contains(
                                map.get("columnName").toString().toLowerCase())))
                .collect(Collectors.toList());

        // 4. 转换所有匹配的Map列表为TableColumn并合并
        List<TableColumn> result = matchedMapLists.stream()
                .flatMap(List::stream)
                .filter(map -> map != null)
                .map(PinyinUtils::convertMapToTableColumn)
                .filter(column -> {
                    // 新增过滤条件：排除特定列名
                    String name = column.getName().toLowerCase();
                    return !name.equals("id")
                            && !name.equals("create_time")
                            && !name.equals("update_time");
                })
                .distinct() // 去重
                .collect(Collectors.toList());

        return result;
    }


    /**
     * 将单个Map转换为TableColumn对象
     *
     * @param map 包含列信息的Map
     * @return 转换后的TableColumn对象
     */
    private static TableColumn convertMapToTableColumn(Map<String, Object> map) {
        TableColumn column = new TableColumn();

        // 设置name
        if (map.containsKey("columnName")) {
            column.setName(map.get("columnName").toString());
        }

        // 设置type
        if (map.containsKey("dataType")) {
            column.setType(map.get("dataType").toString());
        }

        // 设置length - 优先使用maxLength，没有则使用numericPrecision
        if (map.containsKey("maxLength")) {
            column.setLength(Integer.parseInt(map.get("maxLength").toString()));
        } else if (map.containsKey("numericPrecision")) {
            column.setLength(Integer.parseInt(map.get("numericPrecision").toString()));
        } else {
            column.setLength(0); // 默认值
        }

        // 设置comment
        if (map.containsKey("columnComment")) {
            column.setComment(map.get("columnComment").toString());
        }

        // 设置only - 当columnKey为"UNI"时为true
        if (map.containsKey("columnKey")) {
            column.setOnly("UNI".equalsIgnoreCase(map.get("columnKey").toString()));
        } else {
            column.setOnly(false);
        }

        // nullable默认为true，如果需要也可以从map中获取
        column.setNullable(true);

        return column;
    }

    // 需要排除的字段列表
    private static final List<String> EXCLUDED_FIELDS = Arrays.asList("id", "createTime", "updateTime");

    public static List<List<InData>> getAllData(List<?> entities) {
        List<List<InData>> result = new ArrayList<>();

        if (entities == null || entities.isEmpty()) {
            return result;
        }

        for (Object entity : entities) {
            List<InData> inDataList = convertSingleEntity(entity);
            if (!inDataList.isEmpty()) {
                result.add(inDataList);
            }
        }

        return result;
    }

    private static List<InData> convertSingleEntity(Object entity) {
        List<InData> inDataList = new ArrayList<>();

        if (entity == null) {
            return inDataList;
        }

        Class<?> clazz = entity.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            // 跳过排除的字段
            if (EXCLUDED_FIELDS.contains(field.getName())) {
                continue;
            }

            try {
                field.setAccessible(true);
                InData inData = new InData();
                // 转换字段名为下划线格式
                inData.setName(convertToSnakeCase(field.getName()));
                inData.setValue(field.get(entity));

                // 获取Column注解的值作为备注
                Column columnAnnotation = field.getAnnotation(Column.class);
                if (columnAnnotation != null) {
                    inData.setComment(columnAnnotation.name());
                } else {
                    // 如果没有Column注解，尝试获取ApiModelProperty的值
                    ApiModelProperty apiModelProperty = field.getAnnotation(ApiModelProperty.class);
                    if (apiModelProperty != null) {
                        inData.setComment(apiModelProperty.value());
                    } else {
                        inData.setComment(""); // 都没有则留空
                    }
                }
                inDataList.add(inData);
            } catch (IllegalAccessException e) {
                // 处理无法访问字段的情况
                System.err.println("无法访问字段: " + field.getName() + " 在类 " + clazz.getName());
            }
        }

        return inDataList;
    }

    /**
     * 将驼峰命名转换为下划线命名
     * 例如: "ahL2" -> "ah_l2", "userName" -> "user_name"
     */
    private static String convertToSnakeCase(String camelCase) {
        if (camelCase == null || camelCase.isEmpty()) {
            return camelCase;
        }

        StringBuilder result = new StringBuilder();
        result.append(Character.toLowerCase(camelCase.charAt(0)));

        for (int i = 1; i < camelCase.length(); i++) {
            char currentChar = camelCase.charAt(i);
            if (Character.isUpperCase(currentChar)) {
                result.append('_')
                        .append(Character.toLowerCase(currentChar));
            } else {
                result.append(currentChar);
            }
        }

        return result.toString();
    }

    /**
     * 获取汉字首字母
     * @param chinese 中文字符串
     * @return 首字母字符串
     */
    public static String getFirstLetters(String chinese) {
        StringBuilder pinyin = new StringBuilder();
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        
        char[] chars = chinese.toCharArray();
        for (char c : chars) {
            if (c > 128) { // 是汉字
                try {
                    String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
                    if (pinyinArray != null && pinyinArray.length > 0) {
                        pinyin.append(pinyinArray[0].charAt(0));
                    }
                } catch (BadHanyuPinyinOutputFormatCombination e) {
                    e.printStackTrace();
                }
            } else {
                pinyin.append(c); // 非汉字字符原样保留
            }
        }
        return pinyin.toString().toLowerCase()   ;
    }

    public static String sanitizeTableName(String rawName) {
        // 替换所有非法字符为下划线
        String stage1 = rawName.replaceAll("[^a-zA-Z0-9_]", "_");
        //合并连续下划线
        String stage2 = stage1.replaceAll("_+", "_");
        //去除首尾下划线
        String stage3 = stage2.replaceAll("^_|_$", "");
        return stage3.isEmpty() ? "unknown" : stage3;
    }
}